package com.xinqi.modules.course.clazz.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xinqi.common.base.enums.YesNoEnum;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.base.response.PageInfo;
import com.xinqi.common.base.response.Param;
import com.xinqi.common.core.enums.ClassRoleEnum;
import com.xinqi.common.mybatis.data.service.impl.BaseServiceImpl;
import com.xinqi.common.mybatis.utils.Pages;
import com.xinqi.common.mybatis.utils.Queries;
import com.xinqi.modules.course.clazz.convert.ClassJoinAuditConvert;
import com.xinqi.modules.course.clazz.convert.ClassOperationLogConvert;
import com.xinqi.modules.course.clazz.domain.ClassJoinAuditEntity;
import com.xinqi.modules.course.clazz.domain.ClassOperationLogEntity;
import com.xinqi.modules.course.clazz.dto.req.ClassOperationLogCreateDTO;
import com.xinqi.modules.course.clazz.dto.req.ClassOperationLogDeleteDTO;
import com.xinqi.modules.course.clazz.dto.req.ClassOperationLogQueryDTO;
import com.xinqi.modules.course.clazz.dto.req.ClassOperationLogUpdateDTO;
import com.xinqi.modules.course.clazz.dto.rsp.ClassOperationLogResultDTO;
import com.xinqi.modules.course.clazz.manager.ClassJoinAuditManager;
import com.xinqi.modules.course.clazz.mapper.ClassOperationLogMapper;
import com.xinqi.modules.course.clazz.service.ClassJoinAuditService;
import com.xinqi.modules.course.clazz.service.ClassOperationLogService;
import com.xinqi.modules.course.course.enums.ClassAuditJsonParamEnum;
import com.xinqi.modules.course.course.enums.clazz.ClassOperationLogTypeEnum;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 班级日志服务层实现
 *
 * @author: system
 * @date: 2023/01/17
 */
@Service("classOperationLogService")
@RequiredArgsConstructor
public class ClassOperationLogServiceImpl extends BaseServiceImpl<ClassOperationLogMapper, ClassOperationLogEntity> implements ClassOperationLogService {
    private final ClassOperationLogConvert classOperationLogConvert;
    private final ClassJoinAuditConvert classJoinAuditConvert;

    private final ClassJoinAuditManager classJoinAuditManager;

    /**
     * 分页查询 班级日志数据
     */
    @Override
    @DS("slaver")
    public PageInfo<ClassOperationLogResultDTO> page(Param pageable, ClassOperationLogQueryDTO query) {
        IPage<ClassOperationLogResultDTO> page = baseMapper.pageListBy(Pages.page(pageable), query);
        this.setRelationship(page);
        return Pages.convert(page);
    }

    private void setRelationship(IPage<ClassOperationLogResultDTO> page) {
        if (CollectionUtils.isNotEmpty(page.getRecords())) {
            for (ClassOperationLogResultDTO resultDTO : page.getRecords()) {
                if (StringUtils.isNotEmpty(resultDTO.getAuditContent())) {
                    Map<String, String> relationMap = classJoinAuditConvert.paraMap(resultDTO.getAuditContent());
                    if (relationMap.containsKey(ClassAuditJsonParamEnum.学生真实姓名.getCode())) {

                        resultDTO.setStudentName(relationMap.get(ClassAuditJsonParamEnum.学生真实姓名.getCode()));
                    }

                    if (relationMap.containsKey(ClassAuditJsonParamEnum.与学生的关系.getCode())) {
                        resultDTO.setRelationship(relationMap.get(ClassAuditJsonParamEnum.与学生的关系.getCode()));
                    }
                }
            }

        }
    }

    /**
     * 查询 班级日志数据
     */
    @Override
    public List<ClassOperationLogResultDTO> find(ClassOperationLogQueryDTO query) {
        return list(wrapper(query)).stream().map(classOperationLogConvert::convert).collect(Collectors.toList());
    }

    private LambdaQueryWrapper<ClassOperationLogEntity> wrapper(ClassOperationLogQueryDTO query) {
        LambdaQueryWrapper<ClassOperationLogEntity> wrapper = Queries.lambda();
        Queries.accept(query.getId(), v -> wrapper.eq(ClassOperationLogEntity::getId, v));
        Queries.accept(query.getCourseId(), v -> wrapper.eq(ClassOperationLogEntity::getCourseId, v));
        Queries.accept(query.getClassId(), v -> wrapper.eq(ClassOperationLogEntity::getClassId, v));
        Queries.accept(query.getStudentId(), v -> wrapper.eq(ClassOperationLogEntity::getStudentId, v));
        Queries.accept(query.getType(), v -> wrapper.eq(ClassOperationLogEntity::getType, v));
        return wrapper;
    }

    /**
     * 根据id查询 班级日志数据
     */
    @Override
    public ClassOperationLogResultDTO findById(Long id) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(id), "ID不能为空");
        return Optional.ofNullable(baseMapper.selectById(id)).map(classOperationLogConvert::convert).orElse(null);
    }

    /**
     * 新增 班级日志数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insert(ClassOperationLogCreateDTO dto) {
        ClassOperationLogEntity entity = classOperationLogConvert.create(dto);
        save(entity);
        return entity.getId();
    }

    /**
     * 根据id修改 班级日志数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateById(ClassOperationLogUpdateDTO dto) {
        ClassOperationLogEntity old = Optional.ofNullable(getById(dto.getId())).orElseThrow(() -> CommonErrors.BAD_REQUEST.asException("数据不存在"));
        ClassOperationLogEntity entity = classOperationLogConvert.update(dto);
        return updateById(entity);
    }

    /**
     * 根据id删除 班级日志数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteById(Long id) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(id), "ID不能为空");
        return removeById(id);
    }

    /**
     * 根据id删除 班级日志数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteById(ClassOperationLogDeleteDTO dto) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getId()), "ID不能为空");
        return deleteById(dto.getId());
    }

    /**
     * 学生加入班级日志
     *
     * @param courseId  课程id
     * @param classId   班级id
     * @param studentId 学生id
     * @param auditId   审核id
     * @return Boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertStudentOperateLog(Long courseId, Long classId, Long studentId, Long auditId, ClassOperationLogTypeEnum operationLogType) {

        // 获取班级审核信息
        LambdaQueryWrapper<ClassJoinAuditEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ClassJoinAuditEntity::getClassId, classId);
        wrapper.eq(ClassJoinAuditEntity::getStudentId, studentId);
        List<ClassJoinAuditEntity> joinList = classJoinAuditManager.list(wrapper);
        Map<Long, List<ClassJoinAuditEntity>> map = new HashMap<>();
        if (CollectionUtils.isNotEmpty(joinList)) {
            map = joinList.stream().collect(Collectors.groupingBy(ClassJoinAuditEntity::getStudentId));
        }

        ClassOperationLogEntity entity = classOperationLogConvert.convert(courseId, classId, studentId, auditId);
        entity.setType(operationLogType);
        entity.setClassRole(ClassRoleEnum.STUDENT);
        entity.setIsTeacher(YesNoEnum.NO.ordinal());
        entity.setIsTop(YesNoEnum.NO.ordinal());
        if (!map.isEmpty()) {
            List<ClassJoinAuditEntity> list = map.get(studentId);
            if (CollectionUtils.isNotEmpty(list)) {
                entity.setAuditContent(list.get(0).getAuditContent());
            }
        }
        return save(entity);
    }

    @Override
    public Boolean batchInsertStudentOperateLog(Long courseId, Long classId, List<Long> studentIdList, Long auditId, ClassOperationLogTypeEnum operationLogType) {

        // 获取班级审核信息
        LambdaQueryWrapper<ClassJoinAuditEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ClassJoinAuditEntity::getClassId, classId);
        wrapper.in(ClassJoinAuditEntity::getStudentId, studentIdList);
        List<ClassJoinAuditEntity> joinList = classJoinAuditManager.list(wrapper);
        Map<Long, List<ClassJoinAuditEntity>> map = new HashMap<>();
        if (CollectionUtils.isNotEmpty(joinList)) {
            map = joinList.stream().collect(Collectors.groupingBy(ClassJoinAuditEntity::getStudentId));
        }

        List<ClassOperationLogEntity> logList = new ArrayList<>();
        for (Long studentId : studentIdList) {
            ClassOperationLogEntity entity = classOperationLogConvert.convert(courseId, classId, studentId, auditId);
            entity.setType(operationLogType);
            entity.setClassRole(ClassRoleEnum.STUDENT);
            entity.setIsTeacher(YesNoEnum.NO.ordinal());
            entity.setIsTop(YesNoEnum.NO.ordinal());
            if (!map.isEmpty()) {
                List<ClassJoinAuditEntity> list = map.get(studentId);
                if (CollectionUtils.isNotEmpty(list)) {
                    entity.setAuditContent(list.get(0).getAuditContent());
                }
            }
            logList.add(entity);
        }
        return batchSave(logList);
    }

    @Override
    public Boolean batchSave(List<ClassOperationLogEntity> logList) {
        return super.saveBatch(logList);
    }

}
